<?php
namespace pfp\lib {
    
    \defined( '_JEXEC' ) or die( 'Restricted access' );

    /**
     * Description of permsManager
     *
     * @author George Zeakis<zeageorge@google.com>
     */
    class permsManager {

        /**
         *
         * @var permsManager instance
         */
        protected static $_instance = \NULL;

        /**
         *
         * @var array
         */
        protected $_events = array();

        /**
         *
         * @var array
         */
        protected $_vars = \NULL;

        /**
         * 
         * @return permsManager
         */
        public static function Init(deepDynamicContainer $params){
            if( self::$_instance === \NULL ) { 
                self::$_instance = new self();
                self::$_instance->_vars["config"] = $params;
                self::$_instance->registerEvents();
            }
            return self::$_instance;
        }

        /**
         * 
         * @param User $user
         * @param string $type_of_check
         * @param mix $what_to_check
         * @return boolean Returns TRUE if $user Resources contain $what_to_check, FALSE if it does not,  
         *                   or throws an codeExecution_FlowControlException(array('return'=>FALSE)) on error
         * @throws codeExecution_FlowControlException
         */
        public static function check(User $user, $type_of_check, $what_to_check) {
            $tmp = __FUNCTION__."_tmp"; if (isset(self::$_instance->_vars["$tmp"])){ unset(self::$_instance->_vars["$tmp"]); }
            try {
                if (self::$_instance === \NULL){ throw new codeExecution_FlowControlException(array('return'=>\FALSE), "permsManager must be Initialized first before we can use it."); }

                self::$_instance->_vars["$tmp"]["user_object"]       = $user;
                self::$_instance->_vars["$tmp"]["type_of_check"]     = (string)$type_of_check;
                self::$_instance->_vars["$tmp"]["what_to_check"]     = $what_to_check;
                self::$_instance->_vars["$tmp"]["user_resources"]    = (array)self::$_instance->_vars["$tmp"]["user_object"]->get_resources();
                self::$_instance->_vars["$tmp"]["fileName_of_check2load"] = self::$_instance->_vars["config"]->paths->checks_folderPath().
                                                                                    self::$_instance->_vars["$tmp"]["type_of_check"].DS.
                                                                                    self::$_instance->_vars["$tmp"]["type_of_check"].".php";

                $eventData = array('event_name'=>self::$_instance->_events['event_onBefore_UserPermissionsCheck'],'args'=>&self::$_instance->_vars); eventManager::riseEvent($eventData);

                self::$_instance->_vars["$tmp"]["check_results"] = \FALSE;

                if ( \is_readable(self::$_instance->_vars["$tmp"]["fileName_of_check2load"])){
                    try{
                        require_once self::$_instance->_vars["$tmp"]["fileName_of_check2load"];

                        $c = self::$_instance->_vars["config"]->checks->namespace().self::$_instance->_vars["$tmp"]["type_of_check"];
                        
                        $checkController = new $c();

                        $usr_res = self::$_instance->_vars["$tmp"]["user_object"]->get_resources();
                        self::$_instance->_vars["$tmp"]["check_results"] = $checkController->check($usr_res[self::$_instance->_vars["$tmp"]["type_of_check"]],
                                                                                                            self::$_instance->_vars["$tmp"]["what_to_check"]);
                    } catch (\Exception $exc) {
                        $eventData = array('event_name'=>self::$_instance->_events['event_onWarning'],
                                       'args'=>&self::$_instance->_vars, "WARNING"=>array("warning_msg"=>$exc->getMessage(),"exceptionObject"=>$exc),); eventManager::riseEvent($eventData);
                    }
                } else {
                    $eventData = array('event_name'=>self::$_instance->_events['event_onWarning'],
                                       'args'=>&self::$_instance->_vars, "WARNING"=>array("warning_msg"=>
                                           "File [".self::$_instance->_vars["$tmp"]["fileName_of_check2load"]."] does not exists or is not readable.")); eventManager::riseEvent($eventData);
                }

                $eventData = array('event_name'=>self::$_instance->_events['event_onAfter_UserPermissionsCheck'],'args'=>&self::$_instance->_vars); eventManager::riseEvent($eventData);
                
                $re = self::$_instance->_vars["$tmp"]["check_results"]; unset(self::$_instance->_vars["$tmp"]);
                return (boolean)$re;
            } catch (codeExecution_FlowControlException $exc) {
                if (self::$_instance === \NULL){
                    eventManager::riseEvent(array('event_name'=>"event_onError", 'args'=>&$exc));
                    throw new codeExecution_FlowControlException(array('return'=>\FALSE), $exc->getMessage()); return \FALSE;
                } else {
                    self::$_instance->_vars["$tmp"]["errors"] = $exc;
                    $eventData = array('event_name'=>self::$_instance->_events['event_onError'],'args'=>&self::$_instance->_vars); eventManager::riseEvent($eventData);
                    unset(self::$_instance->_vars["$tmp"]); 
                    throw new codeExecution_FlowControlException(array('return'=>\FALSE), $exc->getMessage()); return \FALSE;
                }
            }
        }

        private function registerEvents(){
            self::$_instance->_events = array(
                'event_onStart'                            =>'event_onStart',
                'event_onError'                            =>'event_onError',
                'event_onWarning'                          =>'event_onWarning',

                'event_onBefore_UserPermissionsCheck'=>'event_onBefore_UserPermissionsCheck',
                'event_onAfter_UserPermissionsCheck'=>'event_onAfter_UserPermissionsCheck',
            );
            eventManager::registerEvents(self::$_instance->_events);
        }

        protected function __construct(){}

        protected function __clone(){}
    }
}
?>
